package com.kern.rpcserver;

import com.alibaba.fastjson.JSONObject;
import com.kern.common.bean.Request;
import com.kern.common.bean.Response;

import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.net.Socket;

/**
 * Created by caoshi at 21:23 2021-07-29
 */
public class RpcServerService implements Runnable {

    private Socket socket;

    public RpcServerService(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {

        try {
            InputStream input = socket.getInputStream();
            ObjectInputStream objInput = new ObjectInputStream(input);
            Object obj = objInput.readObject();

            if (obj instanceof Request) {
                Request request = (Request) obj;
                System.out.println(request.getClassName());
                System.out.println(request.getMethodName());
                // 执行目标方法, 返回结果发送给客户端
                Object res = executeTargetMethod(request);

                // 切换输入流
                socket.shutdownInput();

                OutputStream out = socket.getOutputStream();
                ObjectOutputStream objOut = new ObjectOutputStream(out);

                // 封装响应对象, 注意是将这个响应对象写出
                Response response = new Response();
                response.setMessage("success");
                String resJsonStr = JSONObject.toJSONString(res);
                response.setObj(resJsonStr);
                objOut.writeObject(response);

                objOut.close();

                objInput.close();
                input.close();
                socket.close();
            }

        } catch (Exception e) {

        }
    }

    public static Object executeTargetMethod(Request request) {
        Object result = null;
        // 类名
        String className = request.getClassName();
        // 方法名
        String methodName = request.getMethodName();
        try {
            Class<?> clazz = Class.forName(className);
            Method method = clazz.getMethod(methodName);
            Object service = clazz.newInstance();
            result = method.invoke(service);
            System.out.println("目标服务方法执行结果- " + result);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return result;
    }

}
